/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ru.egslava.edittextphonenumber.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.bundle.AbilityInfo;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.multimodalinput.event.KeyEvent;
import ohos.vibrator.agent.VibratorAgent;
import ohos.vibrator.bean.VibrationPattern;

import java.io.IOException;
import java.util.List;
import java.util.Optional;

import br.com.sapereaude.maskedEditText.Log;
import br.com.sapereaude.maskedEditText.MaskedEditText;
import ru.egslava.edittextphonenumber.ResourceTable;

/**
 * 自定义输入框
 *
 * @since 2021-04-12
 */
public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener,
    Animator.StateChangedListener, Component.LongClickedListener {
    private static final String TAG = "MainAbilitySlice";
    private static final int VIBRATION_DURATION = 50;
    private static final int CURSOR_SIZE = 28;
    private static final int TIME = 300;
    private static final int TIME3 = 100;
    private static final int TIME4 = 1500;
    private int width;
    private boolean isButtonShow = false;
    private boolean isFirstAnimation = true;
    private Text title;
    private Text more;
    private Button button;
    private MaskedEditText masked;
    private DirectionalLayout directionalLayout;
    private DirectionalLayout titleBarLayout;
    private DependentLayout componentBackground;
    private AnimatorProperty animatorProperty;
    private AnimatorProperty animatorProperty1;
    private AnimatorProperty moreAnimatorProperty;
    private EventHandler eventHandler;
    private VibratorAgent vibratorAgent;
    private Integer vibratorId;

    /**
     * onStart
     *
     * @param intent 意图
     */
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initVibrator();
        title = (Text) findComponentById(ResourceTable.Id_titleBarText);
        directionalLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_settingLayout);
        titleBarLayout = (DirectionalLayout) findComponentById(ResourceTable.Id_titleBarLayout);
        componentBackground = (DependentLayout) findComponentById(ResourceTable.Id_componentBackground);
        masked = (MaskedEditText) findComponentById(ResourceTable.Id_masked);
        button = (Button) findComponentById(ResourceTable.Id_settings);
        more = (Text) findComponentById(ResourceTable.Id_more); // 更多选项
        masked.setSelectionColor(new Color(Color.getIntColor("#96D2CC"))); // 设置光标选中内容颜色
        eventHandler = new EventHandler(EventRunner.getMainEventRunner());
        try {
            // 设置光标颜色
            ShapeElement shapeElement = new ShapeElement();
            shapeElement.setShape(ShapeElement.LINE); // 设置背景类型
            RgbColor rgbColor = RgbColor.fromArgbInt(Color.getIntColor("#009688"));
            shapeElement.setRgbColors(new RgbColor[]{rgbColor, rgbColor}); // 设置颜色值 起始与结束时的颜色
            shapeElement.setStroke(AttrHelper.vp2px(CURSOR_SIZE, this), rgbColor); // 设置光标高度
            masked.setCursorElement(shapeElement); // 设置光标背景色

            // 获取屏幕宽度
            getDisplayWidth();
            String label = getResourceManager().getElement(ResourceTable.String_app_name).getString(); // 设置label
            title.setText(label);
            directionalLayout.setClickedListener(this); // 设置点击事件
            titleBarLayout.setClickedListener(this); // titleBar点击事件
            titleBarLayout.setLongClickedListener(this); // titleBar长按事件
            componentBackground.setClickedListener(this); // 根布局点击事件
            masked.setClickedListener(this); // 自定义输入框点击事件
            button.setClickedListener(this);
        } catch (IOException error) {
            Log.error(TAG, " IOException " + error.getLocalizedMessage());
        } catch (NotExistException error) {
            Log.error(TAG, "NotExistException" + error.getLocalizedMessage());
        } catch (WrongTypeException error) {
            Log.error(TAG, "WrongTypeException" + error.getLocalizedMessage());
        }
    }

    /**
     * 动画开始
     *
     * @param animator 动画对象
     */
    @Override
    public void onStart(Animator animator) {
    }

    /**
     * 点击事件
     *
     * @param component 点击视图
     */
    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_settingLayout:
                // 出现动画
                animatorProperty = button.createAnimatorProperty();
                animatorProperty.moveFromX(width).moveToX(width - button.getWidth());
                animatorProperty.setDuration(TIME);
                animatorProperty.start();
                isButtonShow = true;
                masked.clearFocus(); // 移除输入框焦点
                break;
            case ResourceTable.Id_settings:
                // 取消动画
                cancelAnimator();
                break;
            case ResourceTable.Id_masked:
            case ResourceTable.Id_componentBackground:
            case ResourceTable.Id_titleBarLayout:
                if (isButtonShow) { // 监听根布局 头部布局,还有输入框点击事件
                    // 取消动画
                    cancelAnimator();
                }
                break;
            default:
                break;
        }
    }

    @Override
    public void onLongClicked(Component component) {
        if (hasVibrator()) {
            startVibrator();
        }
        if (isFirstAnimation) {
            isFirstAnimation = false;
            moreAnimatorProperty = more.createAnimatorProperty();
            moreAnimatorProperty.alphaFrom(0.0f).alpha(1.0f);
            moreAnimatorProperty.setDuration(TIME3);
            moreAnimatorProperty.start();
            AnimationRunnable runnable = new AnimationRunnable();
            eventHandler.postTask(runnable, TIME4);
        } else {
            if (moreAnimatorProperty != null && !moreAnimatorProperty.isRunning()) {
                moreAnimatorProperty = more.createAnimatorProperty();
                moreAnimatorProperty.alphaFrom(0.0f).alpha(1.0f);
                moreAnimatorProperty.setDuration(TIME3);
                moreAnimatorProperty.start();
                AnimationRunnable runnable = new AnimationRunnable();
                eventHandler.postTask(runnable, TIME4);
            }
        }
    }

    private void cancelAnimator() { // 取消设置动画
        animatorProperty1 = button.createAnimatorProperty();
        animatorProperty1.alpha(0);
        animatorProperty1.setDuration(TIME);
        animatorProperty1.setStateChangedListener(this);
        animatorProperty1.start();
        isButtonShow = false;
    }

    /**
     * 屏幕方向改变时回调
     *
     * @param displayOrientation 显示方向
     */
    @Override
    protected void onOrientationChanged(AbilityInfo.DisplayOrientation displayOrientation) {
        super.onOrientationChanged(displayOrientation);
        getDisplayWidth();
    }

    private void getDisplayWidth() { // 获取屏幕宽度
        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(this.getContext());
        Point pt = new Point();
        display.get().getSize(pt);
        width = display.get().getAttributes().width;
    }

    /**
     * 震动器初始化
     */
    private void initVibrator() {
        vibratorAgent = new VibratorAgent();
        List<Integer> vibratorList = vibratorAgent.getVibratorIdList(); // 查询硬件设备上的振动器列表
        if (vibratorList.isEmpty()) {
            vibratorAgent = null;
            return;
        }
        vibratorId = vibratorList.get(0);
    }

    /**
     * 查询指定的振动器是否支持指定的振动效果
     *
     * @return boolean
     */
    private boolean hasVibrator() {
        boolean isSupport = vibratorAgent.isEffectSupport(vibratorId,
            VibrationPattern.VIBRATOR_TYPE_CAMERA_CLICK);
        return isSupport;
    }

    /**
     * 开始震动
     */
    private void startVibrator() {
        vibratorAgent.startOnce(vibratorId, VIBRATION_DURATION); // 创建指定振动时长的一次性振动
    }

    /**
     * 动画停止
     *
     * @param animator 动画对象
     */
    @Override
    public void onStop(Animator animator) {
    }

    /**
     * 动画取消
     *
     * @param animator 动画对象
     */
    @Override
    public void onCancel(Animator animator) {
    }

    /**
     * 动画结束
     *
     * @param animator 动画对象
     */
    @Override
    public void onEnd(Animator animator) {
        if (!animatorProperty1.isRunning()) {
            animatorProperty1.reset(); // 重置按钮状态
        }
    }

    /**
     * 动画暂停
     *
     * @param animator 动画对象
     */
    @Override
    public void onPause(Animator animator) {
    }

    /**
     * 动画重新获取焦点
     *
     * @param animator 动画对象
     */
    @Override
    public void onResume(Animator animator) {
    }

    /**
     * 页面进入后台
     */
    @Override
    protected void onInactive() {
        super.onInactive();
        if (masked != null) {
            masked.cancelCursor();
        }
    }

    /**
     * 监听手势点下
     *
     * @param keyCode 键码
     * @param keyEvent 键盘事件
     * @return boolean处理结果
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
        if (keyCode == KeyEvent.KEY_BACK) {
            if (masked != null) {
                masked.removeAllComponent();
            }
        }
        return super.onKeyDown(keyCode, keyEvent);
    }

    /**
     * 返回键监听
     */
    @Override
    protected void onBackPressed() {
        if (isButtonShow) { // 监听返回键 如果菜单栏的设置按钮出现就消失
            // 取消动画
            cancelAnimator();
            return;
        }
        super.onBackPressed();
    }

    /**
     * 动画执行后自动消失
     *
     * @since 2021-07-28
     */
    private class AnimationRunnable implements Runnable {
        @Override
        public void run() {
            if (moreAnimatorProperty != null) {
                moreAnimatorProperty.alphaFrom(1.0f).alpha(0.0f);
                moreAnimatorProperty.setDuration(TIME3);
                moreAnimatorProperty.start();
            }
        }
    }
}
